home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- MASM
- ; This is a modification of the programme described below (SNIPPER).
- ; 0.0.1 gets all chars on lines between point 1 and point 2
- ; 0.0.2 allows the use of HOME and END keys to move around the screen.
- ; 0.0.3 allows hitting ESC key in filename prompt for entering
- ; completely new file name.
- ; 0.0.4 fixed bug in ESC key during filename entry. If esc hit and
- ; then return, will exit without saving to file. if ESC hit
- ; then chars entered for new filename, will print to file.
- ; 0.0.5 added new option when writing to file. Entering F will now
- ; strip out all multiple spaces and any pipes, as well as will
- ; put 2 spaces after any punctuation. Old write to file
- ; (unformatted) is now option "U"
- ; 0.0.6 fixed problem with help box not displaying all options and
- ; correctly formatting the box.
- ; 0.0.7 fixed help box display so that it is uses it's own character
- ; attributes, and restores original attribute upon exit.
- ; 0.0.8 Added colour to Help Box. Unsure if will work with mono
- ; 0.0.9 gets filename from first 8 chars or from first char to period,
- ; of first line of highlight, + .RTT. Refuses all chars which
- ; filenames can not contain.
- ; 0.1.0 checks for mono display adapter. if present, displays mono
- ; help.
- ; 0.1.1 Modified display of copyright notice.
- ; 0.1.2 Added use of INS key when moving to top_left position. Hitting
- ; INS will move the cursor to the 34th column, which is the
- ; standard starting space for file descriptions on PCB/ProDoor BBSs
- ; 0.1.3 Fixed problem with getting filename, and hitting ESC. Now
- ; resets filechar flag so that if used again after hitting esc,
- ; or entering a new filename, will now find new filename.
- ; Also, fills out full space for filename with 0H after each
- ; filename. Previously, if the new filename was shorter than
- ; the last one entered, there would be residual chars.
- ; 0.1.4 Fixed problem with underscore as part of a filename. Had
- ; accidently included it in the list of chars not acceptable.
- ; 0.1.5 Fixed highlighting problem associated with reading filenames
- ; of 8 chars + ext.
- ; 0.1.6 Program sends "fl filename.ext" to keyboard buffer, for file
- ; flagging on BBS.
- ; 0.1.7 Pruned program of unused or unnecessary functions relating to
- ; SNIPPER
- ; 0.1.8 Extended total filename size to a maximum of 50 chars for
- ; large paths.
- ; 0.1.9 Fixed problem with using the program multiple
- ; times. Wouldn't write more than one file nor would it spit
- ; out more then "F" on the second use in the file flag section.
- ; 0.2.0 Reduced Maximum filename length to 12 places in anticipation of
- ; the use of a path statement on the command line to be added in
- ; an upcomming version.
- ; 0.2.1 Added use of pathname on command line. Path statement will
- ; now be /P=path. Command line must be eithe filesnip by itself
- ; or filesnip rows,cols,/P=path
- ; 0.3.0 No modifications - Found no bugs
- ; 0.4.0 No modifications - Found no bugs
- ; 0.5.0 No modifications - Found no bugs
- ; 0.6.0 No modifications - Found no bugs
- ; 0.7.0 No modifications - Found no bugs
- ; 0.8.0 No modifications - Found no bugs
- ; 0.9.0 No modifications - Found no bugs
- ; 1.0.0 Initial Release - 6 June 1990
- ; 1.0.1 Made use of path statement flag on command line non-case
- ; sensitive.
- ; 1.0.2 Added ESC before flagging of file to download in case user is
- ; in scrollback mode.
- ; 1.1.0 Added reformatting of captured text to make it look better in
- ; the .RTT file. Now, no line will be longer than 72 chars,
- ; with text broken at spaces.
- ; 1.1.1 Added breaking of lines at all appropriate places, ie: hyphens,
- ; slashes, underscores, plus and equal symbols. Also fixed bug
- ; which occured if for some unknown reason a captured line had
- ; more than 72 chars in a row (ie. no white spaces)
- ; 1.2.0 Removed Printer feature as it was more or less useless.
- ; 1.2.1 Got rid of extra carriage return that was placed in .RTT file
- ; at end of text. Was causing problems with program used to
- ; incorporate files into BBS system.
-
-
- ; SNIPPER is a resident utility which allows cutting out a portion
- ; of the screen. The selected portion may be printed, written
- ; to disk or entered in the keyboard buffer. Activate SNIPPER by
- ; pressing CTL-~, then position the cursor in the upper left corner of
- ; the window using the arrow keys. Press CR to fix the first corner,
- ; then expand the window with arrow keys. Finally, type "P" to print,
- ; "F" for disk file, "G" to retrieve or CR for a help menu. Press ESC
- ; any time to exit SNIPPER. When installing SNIPPER, use the optional
- ; parameters to expand it's internal buffer for displays (such as the
- ; EGA) containing more than the standard 25 rows and 80 columns.
- ; SNIPPER [rows,columns]
-
- ;------------------------------------;
- ; BIOS_SEG IS THE ROM-BIOS DATA AREA ;
- ;------------------------------------;
- BIOS_SEG SEGMENT AT 0040H
- ORG 004AH
- CRT_COLS DB ? ;CURRENT NUMBER OF COLUMNS
- ORG 0050H
- CURSOR_POSN DW 8 DUP(?) ;CURRENT CURSOR LOCATION
- ORG 0062H
- ACTIVE_PAGE DB ? ;ACTIVE PAGE FOR CGA AND EGA
- ORG 0084H
- ROWS DB ? ;LAST ROW NUMBER FOR EGA
- BIOS_SEG ENDS
-
- CSEG SEGMENT
- ASSUME CS:CSEG,DS:NOTHING
- ORG 0100H ;BEGINNING FOR .COM PROGRAMS
- START:
- JMP INITIALIZE ;INITIALIZATION CODE IS AT END
- ;--------------------------------;
- ; DATA AREA USED BY THIS PROGRAM ;
- ;--------------------------------;
- HOTKEY EQU 29H ;SCAN CODE FOR "~" KEY
- SHIFT_MASK EQU 00000100B ;MASK FOR CTL KEY
- COPYRIGHT DB 17 DUP(20H),214,44 DUP(196),183
- DB 13,10,17 DUP(20H),186,44 DUP(20H),186
- DB 10,13,17 DUP(20H),186," File-SNIP 1.2.1 (c) 1990 Mad Monk Software ",186
- DB 10,13,17 DUP(20H),186,44 DUP(20H),186
- DB 10,13,17 DUP(20H),186,44 DUP(20H),186
- DB 10,13,17 DUP(20H),186,7,14 DUP(20H),"Hotkey is CTL-~",7,15 DUP(20H),186
- DB 10,13,17 DUP(20H),186,44 DUP(20H),186
- DB 10,13,17 DUP(20H),211,44 DUP(196),189,13,10,"$",1AH
- PROGRAMMER DB "File-SNIP: Scott Penrose. SNIPPER: Tom Kihlken"
- INSTALLED_MSG DB "Already Installed",13,10,"$"
- BAD_DOS_MSG DB "Requires DOS 2.0+",13,10,"$"
- OLDINT09 DD ? ;OLD KEYBOARD BREAK INTERRUPT VECTOR
- OLDINT13 DD ? ;OLD BIOS DISK IO INTERRUPT VECTOR
- OLDINT16 DD ? ;OLD KEYBOARD INTERRUPT VECTOR
- OLDINT21 DD ? ;OLD DOS FUNCTION INTERRUPT VECTOR
- ERR_STAT DB ? ;ERROR STATUS DURING FILE OUTPUT
- PATH_N_FILE DB 128 DUP (0)
- FILE_PATH DB 114 DUP (0)
- FILE_PROMPT DB "Enter Filename: "
- FILENAME DB "FILESNIP.RTT" ;THE DEFAULT FILENAME
- DB 2 DUP (0) ;LEAVE ROOM FOR DRIVE AND PATH
- TEMP_BUFF_START EQU OFFSET INITIALIZE
- TEMP_BUFF_NEXT DW TEMP_BUFF_START ;POINTER TO NEXT KEY IN BUFFER
- TEMP_BUFF_LAST DW TEMP_BUFF_START ;POINTER TO LAST KEY IN BUFFER
- TEMP_BUFF_SIZE EQU 25*(80+2) ;ROOM FOR 25 ROWS OF 80 COLUMNS
- TEMP_BUFF_END DW TEMP_BUFF_START+TEMP_BUFF_SIZE
- BUFF_START EQU OFFSET INITIALIZE+TEMP_BUFF_SIZE
- BUFF_NEXT DW BUFF_START ;POINTER TO NEXT KEY IN BUFFER
- BUFF_LAST DW BUFF_START ;POINTER TO LAST KEY IN BUFFER
- BUFF_SIZE EQU 25*(80+2) ;ROOM FOR 25 ROWS OF 80 COLUMNS
- BUFF_END DW BUFF_START+BUFF_SIZE
- FILE_BUFF_START EQU OFFSET INITIALIZE+TEMP_BUFF_SIZE+BUFF_SIZE
- FILE_BUFF_NEXT DW FILE_BUFF_START ;POINTER TO NEXT KEY IN BUFFER
- FILE_BUFF_LAST DW FILE_BUFF_START ;POINTER TO LAST KEY IN BUFFER
- FILE_BUFF_SIZE EQU 13H ;19 bytes
- FILE_BUFF_END DW FILE_BUFF_START+FILE_BUFF_SIZE
- TOP_LEFT LABEL WORD ;FIRST CORNER OF WINDOW
- LEFT_SIDE DB 0 ;COLUMN NUMBER OF LEFT SIDE
- TOP_ROW DB 0 ;ROW NUMBER OF TOP SIDE
- BOT_RIGHT LABEL WORD ;SECOND CORNER OF WINDOW
- RIGHT_SIDE DB ? ;COLUMN NUMBER OR RIGHT SIDE
- BOT_ROW DB ? ;ROW NUMBER OF BOTTOM
- SEND_CHAR DW ? ;POINTER TO CHARACTER HANDLER
- FILE_SEND_CHAR DW ? ;POINTER TO CHARACTER HANDLER
- HOME_END_HIT LABEL WORD ;if=1 then home was hit
- HOME_END_LOOP DB 0 ;IF=1, then first time in loop
- SEND_KEYS DB 0 ;IF=1, USE KEYSTROKES FROM BUFFER
- FILE_SEND_KEYS DB 0 ;IF=1, USE KEYSTROKES FROM BUFFER
- WRIT_FILE DB 0 ;IF=1, NEED TO WRITE TO DISK
- BUSY_FLAGS DB 0 ;BIT MASKED AS FOLLOWS:
- ; 1 - DOS IS ACTIVE
- ; 2 - BIOS IO IS ACTIVE
- ; 4 - SNIPPER IS ACTIVE
- DOS_STAT DB 0 ;CURRENT DOS FUNCTION
- SPACE_FLAG DB 0 ;Determine if space should be printed
- FILECHAR DB 0 ;
- FILE_EXT DB 0
- CHARS_ON_STACK DB 0 ;How many chars have been printed
- PUNCT_FLAG DB 0 ;was any punctuation found?
- NO_SPACE_FLAG DB 0
- FIRST_CHAR_MARKER DW 0
- HELP_MENU DB 201,21 DUP(205),187
- DB 186," F - File Formatted ",186
- DB 186," Esc- Quit ",186
- DB 200,21 DUP(205),188
- HELP_MENU_ATTR1 DB 23 DUP(4EH) ;ANSI menu
- DB 23 DUP(4EH)
- DB 23 DUP(4EH)
- DB 23 DUP(4EH)
- HELP_MENU_ATTR2 DB 23 DUP(07H) ;ASCII menu
- DB 23 DUP(07H)
- DB 23 DUP(07H)
- DB 23 DUP(07H)
-
- ;------------------------------------------------------------------;
- ; SNIPPER BUILDS THE WINDOW AND ACCEPTS COMMANDS FROM THE KEYBOARD ;
- ;------------------------------------------------------------------;
- SNIPPER PROC NEAR
- ASSUME DS:CSEG, ES:BIOS_SEG
- XOR BX,BX ;BX IS INCREMENT FOR ROW/COLUMN
- GET_KB_KEY1:
- MOV DX,TOP_LEFT ;GET LOCATION OF FIRST CORNER
- ADD DH,BH ;ADD IN THE ROW INCREMENT
- ADD DL,BL ;ADD IN THE COLUMN INCREMENT
- CMP DL,0 ;AT LEFT EDGE OF SCREEN?
- JGE NOT_LEFT_EDGE
- MOV DL,CRT_COLS ;JUMP TO THE RIGHT EDGE
- DEC DL
- NOT_LEFT_EDGE:
- CMP DL,CRT_COLS ;AT RIGHT EDGE OF SCREEN YET?
- JB NOT_RIGHT_EDGE ;IF NOT, KEEP MOVING RIGHT
- XOR DL,DL ;IF YES, WRAP TO LEFT EDGE
- NOT_RIGHT_EDGE:
- CMP DH,0 ;AT TOP OF SCREEN YET?
- JGE NOT_AT_TOP
- MOV DH,ROWS ;JUMP DOWN TO THE BOTTOM
- NOT_AT_TOP:
- CMP DH,ROWS ;AT BOTTOM OF SCREEN?
- JLE NOT_AT_BOTTOM
- XOR DH,DH ;JUMP BACK TO THE TOP
- NOT_AT_BOTTOM:
- MOV TOP_LEFT,DX ;SAVE NEW CORNER LOCATION
- CALL REV_VIDEO ;CHANGE IT TO REVERSE VIDEO
- XOR AH,AH ;BIOS KEYBOARD INPUT
- INT 16H ;GET A KEYSTROKE
- PUSH AX
- CALL REV_VIDEO ;PUT ATTRIBUTE BACK TO NORMAL
- POP AX
- CMP AH,1 ;IS IT ESCAPE?
- JNE NOT_ESC
- RET ;JUST RETURN TO EXIT
- NOT_ESC:
- MOV BX,0FF00H ;INCREMENT TO SUBTRACT ONE ROW
- CMP AH,48H ;IS IT UP ARROW?
- JE GET_KB_KEY1
- MOV BX,0100H ;INCREMENT TO ADD ONE ROW
- CMP AH,50H ;IS IT DOWN ARROW?
- JE GET_KB_KEY1
-
- MOV BX,0001H ;INCREMENT TO ADD ONE COLUMN
- CMP AH,4FH ;IS IT END KEY?
- JE END_HIT ;jump to END_hit
-
- MOV BX,0001H ;INCREMENT TO ADD ONE COLUMN
- CMP AH,52H ;IS IT INS KEY?
- JE INS_HIT ;jump to PLUS_hit
-
- MOV BX,0001H ;INCREMENT TO ADD ONE COLUMN
- CMP AH,4DH ;IS IT RIGHT ARROW?
- JE GET_KB_KEY1
-
- MOV BX,00FFH ;INCREMENT TO SUBTRACT ONE COLUMN
- CMP AH,47H ;Is it home key
- JE HOME_HIT ;jump to home_hit
-
- MOV BX,00FFH ;INCREMENT TO SUBTRACT ONE COLUMN
- CMP AH,4BH ;IS IT LEFT ARROW?
- JNE NOT_LEFT_ARROW
- JMP GET_KB_KEY1
- NOT_LEFT_ARROW:
- XOR BX,BX
- CMP AL,13 ;IS IT A CARRIAGE RETURN?
- JNE NOT_CR
- MOV DX,TOP_LEFT ;A CARRIAGE RETURN WAS PRESSED
- MOV BOT_RIGHT,DX ;INITIALIZE THE SECOND CORNER
- CALL REV_VIDEO ;CHANGE IT BACK TO REVERSE VIDEO
- JMP SHORT GET_KB_KEY2
- NOT_CR:
- JMP GET_KB_KEY1 ;JUST GET ANOTHER KEY
- HOME_HIT:
- MOV DL,0 ;put cursor at beginning of line
- MOV BL,0 ;
- PUSH DX
- MOV DX,TOP_LEFT
- MOV DL,0H
- MOV TOP_LEFT,DX
- POP DX
- JMP GET_KB_KEY1 ;JUST GET ANOTHER KEY
- END_HIT:
- MOV BL,0H ;put cursor at end of line.
- MOV DL,0H ;
- PUSH DX
- MOV DX,TOP_LEFT
- MOV DL,4FH
- MOV TOP_LEFT,DX
- POP DX
- JMP GET_KB_KEY1 ;JUST GET ANOTHER KEY
- INS_HIT:
- MOV BL,0H ;put cursor at 34th column
- MOV DL,0H ;
- PUSH DX
- MOV DX,TOP_LEFT
- MOV DL,21H
- MOV TOP_LEFT,DX
- POP DX
- JMP GET_KB_KEY1 ;JUST GET ANOTHER KEY
- GET_KB_KEY2:
- MOV HOME_END_HIT,0000H ;clear flag for home/end key
- XOR AH,AH
- INT 16H ;GET A KEYSTROKE
- GOT_KEY2: MOV DX,BOT_RIGHT
- CMP AH,48H ;IS IT UP ARROW?
- JNE NEXT_1
- JMP SUB_ROW_1 ;SUBTRACT A ROW FROM WINDOW
- NEXT_1:
- CMP AH,50H ;IS IT DOWN ARROW?
- JNE NEXT_2
- JMP ADD_ROW_1 ;ADD A ROW TO THE WINDOW
- NEXT_2:
- CMP AH,4DH ;IS IT RIGHT ARROW?
- JNE NEXT_3
- JMP ADD_COL ;ADD A COLUMN TO THE WINDOW
- NEXT_3:
- CMP AH,4BH ;IS IT LEFT ARROW?
- JNE NEXT_4
- JMP SUB_COL ;SUBTRACT A COLUMN FROM WINDOW
- NEXT_4:
- CMP AH,47H ;is it home key.
- JNE NEXT_5
- MOV HOME_END_HIT,0001H
- MOV HOME_END_LOOP,01H
- JMP SUB_COL
- NEXT_5:
- CMP AH,4FH ;is it end key?
- JNE NEXT_6
- MOV HOME_END_HIT,0100H
- JMP ADD_COL
- NEXT_6:
- JMP NOT_ARROW_KEY
- SUB_COL:
- CMP DH,TOP_ROW
- JG OK_GO_BACK
- CMP DL,LEFT_SIDE ;DONT ERASE IT COMPLETELY
- JLE GET_KB_KEY2
- OK_GO_BACK:
- CMP DL,0 ;DONT ERASE IT COMPLETELY
- JLE GET_KB_KEY2
- DEC DL ;SUBTRACT A COLUMN
- MOV RIGHT_SIDE,DL ;SAVE NEW RIGHT SIDE COLUMN
- INC DL
- DONT_INC_DL:
- JMP SHORT COL_LOOP
- ADD_COL:
- INC DL ;ADD A COLUMN
- CMP DL,CRT_COLS ;AT RIGHT EDGE OF SCREEN?
- JL ADD_COL_1
- JMP GET_KB_KEY2 ;STOP WHEN SCREEN IS FILLED
- ADD_COL_1:
- MOV RIGHT_SIDE,DL ;SAVE NEW RIGHT SIDE COLUMN
- COL_LOOP:
- CMP HOME_END_HIT,0001H
- JZ COL_LOOP_1
- CMP HOME_END_HIT,0100H
- JZ COL_LOOP_2
- CALL REV_VIDEO ;REVERSE THIS CHARACTER
- JMP GET_KB_KEY2
- COL_LOOP_1:
- CALL REV_VIDEO ;REVERSE THIS CHARACTER
- DEC DL
- JMP SUB_COL
- COL_LOOP_2:
- CALL REV_VIDEO ;REVERSE THIS CHARACTER
- JMP ADD_COL
- SUB_ROW_1:
- CMP DH,TOP_ROW ;AT TOP OF WINDOW?
- JG SUB_ROW_2
- JMP GET_KB_KEY2 ;DONT ERASE IT COMPLETELY
- SUB_ROW_2:
- PUSH DX
- SUB_ROW:
- CALL REV_VIDEO
- DEC DL ;SUBTRACT A COLUMN
- CMP DL,0 ;DONT ERASE IT COMPLETELY
- JL SUB_ROW_PLUS
- JMP SUB_ROW
- SUB_ROW_PLUS:
- POP DX
- PUSH CX
- MOV CX,TOP_LEFT
- INC CH
- CMP CH,DH
- JE ON_SECOND_ROW
- JMP SUB_ROW_PLUS_1
- ON_SECOND_ROW:
- CMP CL,DL
- JLE SUB_ROW_PLUS_1
- MOV DL,CL
- MOV BOT_RIGHT,DX
- SUB_ROW_PLUS_1:
- POP CX
- DEC DH
- MOV BOT_ROW,DH
- PUSH DX
- SUB_ROW_PLUS_2:
- CMP DL,79
- JGE AT_END
- INC DL
- CALL REV_VIDEO
- JMP SUB_ROW_PLUS_2
- AT_END:
- POP DX
- JMP GET_KB_KEY2
-
-
- ADD_ROW_1:
- CMP DH,ROWS ;AT BOTTOM OF SCREEN?
- JL ADD_ROW_1_1
- JMP GET_KB_KEY2 ;STOP WHEN SCREEN IS FILLED
- ADD_ROW_1_1:
- PUSH DX
- ADD_ROW:
- CMP DL,79
- JZ SKIP_INC
- INC DL
- CALL REV_VIDEO
- SKIP_INC:
- CMP DL,78
- JG ADD_ROW_PLUS
- JMP ADD_ROW
- ADD_ROW_PLUS:
- POP DX
- CMP DH,ROWS ;AT BOTTOM OF SCREEN?
- JL NOT_BOT
- JMP GET_KB_KEY2 ;STOP WHEN SCREEN IS FILLED
- NOT_BOT:
- INC DH
- MOV BOT_ROW,DH
- ROW_LOOP:
- CALL REV_VIDEO ;REVERSE THIS CHARACTER
- DEC DL ;MOVE TO NEXT COLUMN
- CMP DL,0 ;AT LEFT EDGE YET?
- JGE ROW_LOOP ;CONTINUE UNTIL AT LEFT EDGE
- JMP GET_KB_KEY2
- NOT_ARROW_KEY:
- MOV TEMP_BUFF_NEXT,TEMP_BUFF_START
- MOV TEMP_BUFF_LAST,TEMP_BUFF_START
- MOV FILE_BUFF_NEXT,FILE_BUFF_START
- MOV FILE_BUFF_LAST,FILE_BUFF_START
- MOV SEND_CHAR,OFFSET BUFF_CHAR
- CMP AH,21H ;IS IT THE "F" KEY
- JNE NOT_F
- MOV WRIT_FILE,0
- MOV FILE_SEND_CHAR,OFFSET FILE_BUFF_CHAR
- CALL GET_FILENAME
- CMP WRIT_FILE,-1 ;WAS ESCAPE REQUESTED?
- JE ERASE_BOX
- CALL FORMAT_OUTPUT
- CALL COPY_TO_REG_BUFF
- MOV WRIT_FILE,1
- MOV FILE_SEND_KEYS,01H
- TEST BUSY_FLAGS,00000011B ;IS INT21 OR INT13 BUSY?
- JNZ RETURN ;IF YES, WAIT TILL LATER
- CALL WRITE_TO_FILE ;IF NOT, DO IT NOW
- RETURN:
- RET
- NOT_F:
- CMP AH,1 ;IS IT ESCAPE?
- JE ERASE_BOX ;IF YES, ERASE BOX AND EXIT
- CMP AL,13 ;IS IT A CARRIAGE RETURN?
- JE DISPLAY_HELP ;IF YES, DISPLAY HELP
- JMP GET_KB_KEY2 ;OTHERWISE JUST GET ANOTHER KEY
- ERASE_BOX:
- MOV SEND_CHAR,OFFSET RETURN
- JMP FORMAT_OUTPUT
- DISPLAY_HELP:
- CALL EXCHANGE_HELP ;PUT UP THE HELP MENU
- XOR AH,AH
- INT 16H ;GET ANOTHER KEYSTROKE
- PUSH AX ;SAVE THE KEYSTROKE
- CALL EXCHANGE_HELP ;PULL DOWN THE HELP MENU
- POP AX ;GET BACK THE KEYSTROKE
- JMP GOT_KEY2
- ;*********************************************************************
- REV_VIDEO:
- CALL READ_CHAR ;READ CHARACTER AND ATTRIBUTE
- MOV BL,AH ;SAVE ATTRIBUTE IN BL
- AND BL,10001000B ;GET BLINK AND INTENSITY BITS
- AND AH,01110111B ;NOW LOOK ONLY AT COLOR BITS
- MOV CL,4 ;ROTATE FOUR COUNTS
- ROR AH,CL ;ROTATE FOREGROUND AND BACKGROUND
- OR BL,AH ;PUT BACK BLINK AND INTENSITY BITS
- CALL DISPLAY_CHAR ;WRITE CHARACTER AND ATTRIBUTE
- RET
- ;*********************************************************************
- ;---------------------------------------------------------------------;
- ; Proceedure to read char off screen, and send to file formatted.
- ; 11-05-90 12:15am
- ;---------------------------------------------------------------------;
- FORMAT_OUTPUT:
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- MOV DX,TOP_LEFT ;GET LOCATION OF FIRST CORNER
- MOV SPACE_FLAG,00H
- MOV PUNCT_FLAG,00H
- MOV CHARS_ON_STACK,00H
- READ_LOOP_NEW:
- CALL REV_VIDEO
- CALL READ_CHAR
- CMP AL,20H
- JNE READ_LOOP_NEW_1
- JMP WAS_SPACE
- READ_LOOP_NEW_1:
- CMP AL,7CH
- JNE NOT_PIPE
- JMP MOVE_TO_NEXT_CHAR
- NOT_PIPE:
- CMP AL,21H ;is it a "!"
- JNE NOT_PIPE_1
- JMP PUNCT
- NOT_PIPE_1:
- CMP AL,2EH ;is it a "."
- JNE NOT_PERIOD
- JMP PUNCT
- NOT_PERIOD:
- CMP AL,3FH ;is it a "?"
- JNE NOT_QUESTION
- JMP PUNCT
- NOT_QUESTION:
- CMP AL,3AH ;is it a ":"
- JNE NOT_COLON
- JMP PUNCT
- NOT_COLON:
- CMP AL,3BH ;is it a ";"
- JNE NOT_SEMICOLON
- JMP PUNCT
- NOT_SEMICOLON:
- READ_NEW_1:
- CMP SPACE_FLAG,01
- JE SPACE_SET
- CALL SEND_CHAR
- INC CHARS_ON_STACK
- MOVE_TO_NEXT_CHAR:
- CMP DH,BOT_ROW
- JE LAST_LINE_NEW
- INC DL
- CMP DL,79
- JG MOVE_1
- JMP READ_LOOP_NEW
- MOVE_1:
- PUSH AX
- MOV AL,20H
- CALL SEND_CHAR
- POP AX
- MOV CHARS_ON_STACK,00H
- MOV SPACE_FLAG,00H
- MOV PUNCT_FLAG,00H
- INC DH
- MOV DL,0
- CMP DH,BOT_ROW
- JG MOVE_3
- JMP READ_LOOP_NEW
- MOVE_3:
- CALL REV_VIDEO
- LAST_LINE_NEW:
- INC DL
- CMP DL,RIGHT_SIDE
- JG LAST_LINE_NEW_1
- JMP READ_LOOP_NEW
- LAST_LINE_NEW_1:
- CALL CR_LF
- POP DX
- POP CX
- POP BX
- POP AX
- RET
- SPACE_SET:
- CMP CHARS_ON_STACK,0
- JE NO_PUNCT_FLAG
- PUSH AX
- MOV AX,0020H
- CALL SEND_CHAR
- POP AX
- INC CHARS_ON_STACK
- CMP PUNCT_FLAG,01H
- JNE NO_PUNCT_FLAG
- MOV PUNCT_FLAG,00H
- PUSH AX
- MOV AX,0020H
- CALL SEND_CHAR
- POP AX
- INC CHARS_ON_STACK
- CALL SEND_CHAR
- INC CHARS_ON_STACK
- MOV SPACE_FLAG,00H
- JMP MOVE_TO_NEXT_CHAR
- NO_PUNCT_FLAG:
- CALL SEND_CHAR
- INC CHARS_ON_STACK
- MOV SPACE_FLAG,00H
- JMP MOVE_TO_NEXT_CHAR
- PUNCT:
- CMP CHARS_ON_STACK,0
- JNE PUNCT_1
- JMP READ_NEW_1
- PUNCT_1:
- MOV PUNCT_FLAG,01H
- JMP READ_NEW_1
- WAS_SPACE:
- MOV SPACE_FLAG,01H
- JMP MOVE_TO_NEXT_CHAR
- ;*********************************************************************
- COPY_TO_REG_BUFF:
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- MOV AX,TEMP_BUFF_START
- MOV DX,TEMP_BUFF_START
- MOV CX,BUFF_START
- BUFFER_EXCHANGE_LOOP:
- MOV BX,0048H
- PUSH DX
- INC DX
- MOV FIRST_CHAR_MARKER,DX
- DEC DX
- ADD DX,BX
- MOV BX,DX
- POP DX
- CMP BX,TEMP_BUFF_LAST
- JLE BUFF_CHECKING_LOOP
- JMP BUFF_EXCHNG_END
- BUFF_CHECKING_LOOP:
- PUSH AX
- MOV AX,[BX]
- CMP AL,20H
- JE FOUND_SPACE_BEFORE_72_1
- CMP AL,5CH
- JE FOUND_SPACE_BEFORE_72_1
- CMP AL,2FH
- JE FOUND_SPACE_BEFORE_72_1
- CMP AL,5FH
- JE FOUND_SPACE_BEFORE_72_1
- CMP AL,2BH
- JE FOUND_SPACE_BEFORE_72_1
- CMP AL,2DH
- JE FOUND_SPACE_BEFORE_72_1
- CMP BX,FIRST_CHAR_MARKER
- JLE NO_SPACE_IN_LINE
- POP AX
- DEC BX
- JMP BUFF_CHECKING_LOOP
- NO_SPACE_IN_LINE:
- PUSH DX
- MOV DX,BX
- ADD DX,47H
- MOV BX,DX
- POP DX
- MOV NO_SPACE_FLAG,01H
- FOUND_SPACE_BEFORE_72_1:
- POP AX
- FOUND_SPACE_BEFORE_72:
- CMP AX,BX
- JG FINISHED_WITH_LINE
- PUSH BX
- PUSH DX
- MOV BX,AX
- MOV DX,[BX]
- MOV BX,CX
- MOV [BX],DX
- POP DX
- POP BX
- INC CX
- INC AX
- JMP FOUND_SPACE_BEFORE_72
- FINISHED_WITH_LINE:
- CMP NO_SPACE_FLAG,01H
- JNE NO_HYPHEN_NEEDED
- MOV NO_SPACE_FLAG,00H
- PUSH BX
- PUSH DX
- MOV DX,2DH
- MOV BX,CX
- MOV [BX],DX
- POP DX
- POP BX
- INC CX
- NO_HYPHEN_NEEDED:
- PUSH BX
- PUSH DX
- MOV DX,0DH
- MOV BX,CX
- MOV [BX],DX
- POP DX
- POP BX
- INC CX
- PUSH BX
- PUSH DX
- MOV DX,0AH
- MOV BX,CX
- MOV [BX],DX
- POP DX
- POP BX
- INC CX
- MOV DX,AX
- JMP BUFFER_EXCHANGE_LOOP
- BUFF_EXCHNG_END:
- CMP AX,TEMP_BUFF_LAST
- JGE BUFF_EXCHANGE_RET
- PUSH BX
- PUSH DX
- MOV BX,AX
- MOV DX,[BX]
- MOV BX,CX
- MOV [BX],DX
- POP DX
- POP BX
- INC CX
- INC AX
- JMP BUFF_EXCHNG_END
- BUFF_EXCHANGE_RET:
- ;PUSH BX
- ;PUSH DX
- ;MOV DX,0DH
- ;MOV BX,CX
- ;MOV [BX],DX
- ;POP DX
- ;POP BX
- ;INC CX
- ;PUSH BX
- ;PUSH DX
- ;MOV DX,0AH
- ;MOV BX,CX
- ;MOV [BX],DX
- ;POP DX
- ;POP BX
- MOV BUFF_LAST,CX
- POP DX
- POP CX
- POP BX
- POP AX
- RET
- ;*********************************************************************
- CR_LF:
- MOV AL,13
- CALL SEND_CHAR ;SEND A CARRIAGE RETURN
- MOV AL,10
- CALL SEND_CHAR ;SEND A LINE FEED
- RET
- ;*********************************************************************
- DISPLAY_CHAR:
- PUSH BX ;SAVE THE ATTRIBUTE
- CALL GET_CURS_ADDR ;GET ADDRESS OF BIOS CURSOR
- MOV ES:[BX],DX ;TELL BIOS WHERE THE CURSOR IS
- POP BX ;GET BACK THE ATTRIBUTE
- MOV BH,ACTIVE_PAGE ;GET ACTIVE PAGE
- PUSH CX ;SAVE THE LOOP COUNT
- MOV CX,1 ;WRITE 1 CHARACTER
- MOV AH,9 ;WRITE CHARACTER AND ATTRIBUTE
- INT 10H
- POP CX ;RECOVER LOOP COUNT
- RET ;DONE WRITING THE CHARACTER
- ;*********************************************************************
- READ_CHAR:
- CALL GET_CURS_ADDR ;GET ADDRESS OF BIOS CURSOR
- MOV ES:[BX],DX ;TELL BIOS WHERE THE CURSOR IS
- MOV BH,ACTIVE_PAGE ;GET ACTIVE PAGE
- MOV AH,8 ;BIOS FUNCTION TO READ CHARACTER
- INT 10H ;READ THE CHARACTER/ATTRIBUTE
- RET
- ;*********************************************************************
- PRINT_CHAR:
- PUSH DX
- XOR AH,AH ;USE FUNCTION 0
- XOR DX,DX ;PRINTER NUMBER 0
- INT 17H ;BIOS PRINT CHARACTER FUNCTION
- ROR AH,1 ;LOOK AT BIT ZERO
- JNC PRINT_OK ;DID A TIMEOUT OCCUR?
- MOV SEND_CHAR,OFFSET RETURN
- PRINT_OK:
- POP DX
- RET ;DONE PRINTING CHARACTER
- ;*********************************************************************
- BUFF_CHAR:
- MOV BX,TEMP_BUFF_LAST ;GET LOCATION OF LAST CHARACTER
- MOV [BX],AL ;PUT THE CHARACTER IN BUFFER
- INC BX ;ADVANCE THE POINTER
- MOV TEMP_BUFF_LAST,BX ;CHECK FOR BUFFER FULL
- CMP BX,TEMP_BUFF_END ;IS THE BUFFER FULL YET?
- JNE BUFF_OK ;IF NOT, KEEP GOING
- MOV SEND_CHAR,OFFSET RETURN
- BUFF_OK:
- RET ;NOW ITS IN THE BUFFER
- ;*********************************************************************
- FILE_BUFF_CHAR:
- MOV BX,FILE_BUFF_LAST ;GET LOCATION OF LAST CHARACTER
- MOV [BX],AL ;PUT THE CHARACTER IN BUFFER
- INC BX ;ADVANCE THE POINTER
- MOV FILE_BUFF_LAST,BX ;CHECK FOR BUFFER FULL
- CMP BX,FILE_BUFF_END ;IS THE BUFFER FULL YET?
- JNE FILE_BUFF_OK ;IF NOT, KEEP GOING
- MOV FILE_SEND_CHAR,OFFSET RETURN
- FILE_BUFF_OK:
- RET ;NOW ITS IN THE BUFFER
- ;*********************************************************************
- GET_CURS_ADDR:
- MOV BL,ACTIVE_PAGE ;GET THE CURRENT PAGE NUMBER
- XOR BH,BH ;CONVERT TO A WORD OFFSET
- SHL BX,1 ;TIMES TWO FOR A WORD
- ADD BX,OFFSET CURSOR_POSN ;ADD IN BASE ADDRESS
- RET
- ;*********************************************************************
- EXCHANGE_HELP:
- XOR DX,DX ;START AT TOP LEFT CORNER
- PUSH DI
- LEA SI,HELP_MENU
- MOV AH,15
- INT 10H
- CMP AL,7
- JE MONO_HELP
- LEA DI,HELP_MENU_ATTR1
- JMP EXCHANGE_LOOP
- MONO_HELP:
- LEA DI,HELP_MENU_ATTR2
- EXCHANGE_LOOP:
- CMP DL,23 ;AT LAST COLUMN IN THIS ROW YET?
- JL SWAP_CHAR
- XOR DL,DL ;BACK TO FIRST COLUMN
- INC DH ;DO THE NEXT ROW
- CMP DH,4 ;AT LAST ROW YET?
- JL SWAP_CHAR ;QUIT WHEN LAST ROW IS DONE
- POP DI
- RET
- SWAP_CHAR:
- CALL READ_CHAR ;READ CHARACTER AT THIS POSITION
- XCHG AL,CS:[SI] ;SWAP WITH THE HELP TEXT
- XCHG AH,CS:[DI] ;SWAP WITH THE HELP TEXT
- MOV BL,AH ;ATTRIBUTE IS THE SAME
- CALL DISPLAY_CHAR ;PUT NEW CHARACTER ON SCREEN
- INC DL ;POINT TO NEXT POSITION
- INC SI
- INC DI
- JMP EXCHANGE_LOOP
- ;*********************************************************************
- TEST_FILENAME_CHAR:
- CMP AL,2EH
- JE FILECHAR_1
- CMP AL,20H
- JLE FILECHAR_1
- CMP AL,22H
- JE FILECHAR_1
- CMP AL,25H
- JE FILECHAR_1
- CMP AL,2AH
- JE FILECHAR_1
- CMP AL,2BH
- JE FILECHAR_1
- CMP AL,2CH
- JE FILECHAR_1
- CMP AL,2FH
- JE FILECHAR_1
- CMP AL,3AH
- JE FILECHAR_1
- CMP AL,3BH
- JE FILECHAR_1
- CMP AL,3CH
- JE FILECHAR_1
- CMP AL,3DH
- JE FILECHAR_1
- CMP AL,3EH
- JE FILECHAR_1
- CMP AL,7FH
- JGE FILECHAR_1
- CMP AL,5BH
- JE FILECHAR_1
- CMP AL,5CH
- JE FILECHAR_1
- CMP AL,5DH
- JE FILECHAR_1
- CMP AL,5EH
- JE FILECHAR_1
- CMP AL,60H
- JE FILECHAR_1
- CMP FILE_EXT,00H
- JE NOT_EXTEN
- CMP CL,04H
- JE FILECHAR_1
- RET
- NOT_EXTEN:
- CMP CL,08H
- JE FILECHAR_1
- RET
- FILECHAR_1:
- MOV FILECHAR,01
- RET
- GET_FILENAME:
- PUSH BX
- PUSH AX
- MOV AX,1BH
- CALL FILE_SEND_CHAR
- MOV AX,0046H
- CALL FILE_SEND_CHAR
- MOV AX,004CH
- CALL FILE_SEND_CHAR
- MOV AX,0020H
- CALL FILE_SEND_CHAR
- POP AX
- PUSH DI
- PUSH SI
- MOV FILE_EXT,00H
- MOV FILECHAR,00H
- PUSH DX
- PUSH CX
- MOV CL,00H
- MOV DX,TOP_LEFT
- MOV DL,0
- LEA SI,FILENAME
- GET_FILENAME_1:
- CALL READ_CHAR
- CALL TEST_FILENAME_CHAR
- CMP FILECHAR,00H
- JNE END_OF_FILENAME_1
- CMP FILE_EXT,00H
- JNE FILE_EXTEN
- MOV CS:[SI],AL
- INC SI
- FILE_EXTEN:
- CALL FILE_SEND_CHAR
- INC DL
- INC CL
- JMP GET_FILENAME_1
- END_OF_FILENAME_1:
- CMP CL,0
- JE END_OF_FILENAME_A
- CMP FILE_EXT,01H
- JE AT_END_OF_FILENAME
- MOV FILECHAR,00H
- MOV FILE_EXT,01H
- JMP FILE_EXTEN
- AT_END_OF_FILENAME:
- MOV AL,0AH
- CALL FILE_SEND_CHAR
- MOV AL,0DH
- CALL FILE_SEND_CHAR
- MOV AL,2EH
- MOV CS:[SI],AL
- INC SI
- MOV AL,52H
- MOV CS:[SI],AL
- INC SI
- MOV AL,54H
- MOV CS:[SI],AL
- INC SI
- MOV AL,54H
- MOV CS:[SI],AL
- INC SI
- FILL_TO_END:
- CMP CL,0DH
- JE END_OF_FILENAME_A
- MOV AL,0H
- MOV CS:[SI],AL
- INC CL
- INC SI
- JMP FILL_TO_END
- END_OF_FILENAME_A:
- POP CX
- POP DX
- LEA SI,FILE_PROMPT ;POINT TO THE PROMPT FOR SOURCE
- XOR DI,DI ;USE THE PSP FOR BUFFER
- XOR DX,DX ;PUT PROMPT AT TOP LEFT CORNER
- MOV CX,29 ;USE MAX OF 40 CHARACTERS
- POP BX
- DISPLAY_PROMPT:
- PUSH CX ;SAVE LOOP COUNT
- CALL READ_CHAR ;GET CHARACTER ON THIS LINE
- MOV CS:[DI],AX ;STORE IT IN THE PSP
- INC DI ;ADD TWO FOR NEXT CHARACTER
- INC DI
- MOV AL,CS:[SI] ;GET NEXT PROMPT CHARACTER
- INC SI ;NEXT CHARACTER IN PROMPT
- MOV BL,47H ;ATTRIBUTE FOR PROMPT
- CALL DISPLAY_CHAR ;PUT UP THE PROMPT CHARACTER
- INC DL ;POINT TO NEXT COLUMN
- POP CX ;GET BACK LOOP COUNT
- LOOP DISPLAY_PROMPT ;ENTIRE PROMPT AND FILENAME
- FIND_LAST_LETTER:
- DEC SI ;BACKUP TO LAST LETTER
- DEC DL ;BACKUP TO LAST COLUMN
- CMP BYTE PTR [SI],0 ;IS THIS A LETTER?
- JE FIND_LAST_LETTER;BACKUP UNTILL A LETTER IS FOUND
- INC DL ;PUT BLINKING BOX AT LAST LETTER
- READ_KB:
- MOV AL,219 ;ASCII FOR BOX CHARACTER
- MOV BL,47H+80H ;MAKE IT A BLINKING BOX CHARACTER
- CALL DISPLAY_CHAR ;WRITE THE BLINKING BOX
- XOR AH,AH ;FUNCTIO 0 TO GET NEXT KEY
- INT 16H ;BIOS KEYBOARD INPUT
- CMP AL,13 ;IS IT A CARRIAGE RETURN?
- JE ERASE_PROMPT
- CMP AL,8 ;IS IT A BACKSPACE?
- JE BACK_SPACE
- CMP AH,1 ;IS IT ESCAPE?
- JNE READ_KBDRD_2
- MOV WRIT_FILE,-1 ;INDICATE ESCAPE IS REQUESTED
- READ_KBDRD_1:
- CMP DL,16 ;AT BEGINNING OF LINE?
- JLE READ_KB ;IF YES, CAN'T BACKUP FROM HERE
- MOV AL,0 ;WRITE A NORMAL BLANK (ASCII 0)
- MOV BL,47H ;ATTRIBUTE FOR FILENAME
- CALL DISPLAY_CHAR ;WRITE THE LETTER
- DEC DL ;BACKUP THE CURSOR
- JMP READ_KBDRD_1
- READ_KBDRD_2:
- CMP AL,"." ;IS IT A VALID LETTER?
- JL READ_KB
- CMP AL,"z" ;IS IT A VALID LETTER?
- JG READ_KB
- CMP DL,28 ;ONLY ALLOW 40 CHARACTERS
- JGE READ_KB
- TTY_KEY:
-
- MOV WRIT_FILE,0 ;FIX ESCAPE HIT THEN CHARS.
- MOV BL,47H ;ATTRIBUTE FOR FILENAME
- CALL DISPLAY_CHAR ;WRITE THE LETTER
- INC DL ;MOVE TO NEXT COLUMN
- JMP READ_KB ;GET ANOTHER KEYSTROKE
- BACK_SPACE:
- CMP DL,16 ;AT BEGINNING OF LINE?
- JLE READ_KB ;IF YES, CAN'T BACKUP FROM HERE
- MOV AL,0 ;WRITE A NORMAL BLANK (ASCII 0)
- MOV BL,47H ;ATTRIBUTE FOR FILENAME
- CALL DISPLAY_CHAR ;WRITE THE LETTER
- DEC DL ;BACKUP THE CURSOR
- JMP READ_KB ;THEN GET THE NEXT KEY
- ESC_RET:
- MOV WRIT_FILE,-1 ;INDICATE ESCAPE IS REQUESTED
- ERASE_PROMPT:
- XOR AL,AL ;GET RID OF THE CURSOR
- CALL DISPLAY_CHAR ;WRITE THE LETTER
- LEA DI,FILE_PROMPT ;COPY TO FILENAME
- XOR SI,SI ;COPY FROM PSP
- XOR DX,DX ;PROMPT IS AT ROW ZERO
- MOV CX,29 ;COPY ALL 40 CHARACTERS
- ERASE_LOOP:
- CALL READ_CHAR ;GET CHARACTER ON THIS LINE
- MOV CS:[DI],AL ;PUT IN BACK IN MEMORY
- INC DI
- MOV AX,CS:[SI] ;GET THE ORIGINAL CHARACTER BACK
- MOV BL,AH ;PUT ATTRIBUTE INTO BL
- INC SI
- INC SI
- CALL DISPLAY_CHAR ;WRITE ORIGINAL CHARACTER
- INC DL ;MOVE TO NEXT COLUMN
- LOOP ERASE_LOOP ;ERASE THE ENTIRE PROMPT
- POP SI
- POP DI
- RET
- SNIPPER ENDP
-
- ;---------------------------------------------------------------------;
- ; THIS COPIES THE BUFFER CONTENTS TO A FILE. IT SHOULD ONLY BE CALLED ;
- ; WHEN DOS IS IN A STABLE AND REENTRANT CONDITION. ;
- ;---------------------------------------------------------------------;
- WRITE_TO_FILE PROC NEAR
- ASSUME DS:NOTHING, ES:NOTHING
- MOV WRIT_FILE,0 ;TURN OFF REQUEST FLAG
- PUSH AX ;MUST PRESERVE ALL REGISTERS
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DS
- PUSH ES
- PUSH CS
- POP DS
- ASSUME DS:CSEG ;DS POINTS TO OUR CODE SEGMENT
- MOV AX,3524H ;GET DOS CRITICAL ERROR VECTOR
- INT 21H ;DOS FUNCTION TO GET VECTOR
- PUSH BX ;SAVE OLD VECTOR ON STACK
- PUSH ES
- ; REPLACE THE DOS SEVERE ERROR INTERRUPT WITH OUR OWN ROUTINE.
- MOV DX,OFFSET NEWINT24
- MOV AX,2524H ;SETUP TO CHANGE INT 24h VECTOR
- INT 21H ;CHANGE DOS SEVERE ERROR VECTOR
- LEA SI,PATH_N_FILE
- PATH_N_FILE_LOOP:
- CMP BYTE PTR[SI],0
- JE PNFL_DONE
- MOV BYTE PTR[SI],0
- INC SI
- JMP PATH_N_FILE_LOOP
- PNFL_DONE:
- LEA DI,PATH_N_FILE
- LEA SI,FILE_PATH
- TRANSFER_PATH_N_FILE:
- CMP BYTE PTR[SI],0
- JE TPNF_DONE
- PUSH BX
- MOV BL,[SI]
- MOV [DI],BL
- POP BX
- INC SI
- INC DI
- JMP TRANSFER_PATH_N_FILE
- TPNF_DONE:
- LEA SI,FILENAME
- ADD_FILENAME_LOOP:
- CMP BYTE PTR[SI],0
- JE AFL_DONE
- PUSH BX
- MOV BL,[SI]
- MOV [DI],BL
- POP BX
- INC SI
- INC DI
- JMP ADD_FILENAME_LOOP
- AFL_DONE:
- MOV DX,OFFSET PATH_N_FILE ;POINT TO FILENAME
- ; FIRST TRY TO OPEN THE FILE. IF DOS RETURNS WITH THE CARRY FLAG SET,
- ; THE FILE DIDN'T EXIST AND WE MUST CREATE IT. ONCE THE FILE IS OPENED,
- ; ADVANCE THE FILE POINTER TO THE END OF FILE TO APPEND.
- MOV AX,3D02H ;DOS FUNCTION TO OPEN FILE
- INT 21H ;DOS WILL RETURN WITH CARRY FLAG
- JC FILE_NOT_FOUND ;SET IF FILE DOESN'T EXIST.
- MOV BX,AX ;KEEP HANDLE IN BX ALSO
- XOR CX,CX ;MOVE DOS FILE POINTER TO THE
- XOR DX,DX ;END OF THE FILE. THIS LETS US
- MOV AX,4202H ;APPEND THIS TO AN EXISTING FILE
- INT 21H ;DOS FUNCTION TO MOVE POINTER
- JNC WRITE_FILE ;IF NO ERROR, CONTINUE TO WRITE
- DOS_ERROR:
- CMP ERR_STAT,0 ;DID A SEVERE ERROR OCCUR?
- JNE REP_VECTOR ;IF SEVERE ERROR, JUST QUIT
- JMP SHORT CLOSE_FILE;JUST CLOSE THE FILE
-
- FILE_NOT_FOUND: CMP ERR_STAT,0 ;DID A SEVERE ERROR OCCUR?
- JNE REP_VECTOR ;IF SEVERE ERROR, JUST QUIT
- MOV CX,0020H ;ATTRIBUTE FOR NEW FILE
- MOV AH,3CH ;CREATE FILE FOR WRITING
- INT 21H ;DOS FUNCTION TO CREATE FILE
- JC DOS_ERROR ;ON ANY ERROR, TAKE JUMP
- MOV BX,AX ;SAVE HANDLE IN BX
- WRITE_FILE: MOV DX,BUFF_START ;POINT TO BUFFER
- MOV CX,BUFF_LAST ;GET BUFFER POINTER
- SUB CX,DX ;NUMBER OF CHARS IN BUFFER
- MOV AH,40H ;DOS WRITE TO A DEVICE FUNCTION
- INT 21H ;WRITE TO THE FILE
- CLOSE_FILE:
- MOV AH,3EH ;DOS FUNCTION TO CLOSE THE FILE
- INT 21H
- REP_VECTOR:
- POP DS ;GET INT 24H VECTOR FROM STACK
- POP DX
- MOV AX,2524H ;RESTORE CRITICAL ERROR VECTOR
- INT 21H ;DOS FUNCTION TO CHANGE VECTOR
- POP ES ;FINALLY RESTORE ALL REGISTERS
- POP DS
- POP DX
- POP CX
- POP BX
- POP AX
- RET ;FINISHED WRITING TO DISK
- WRITE_TO_FILE ENDP
- ;---------------------------------------------------------------------;
- ; INTERRUPT 09 ROUTINE. WATCH FOR TRIGGER KEY TO POP UP.
- ;---------------------------------------------------------------------;
- NEWINT09 PROC FAR
- ASSUME DS:NOTHING, ES:NOTHING
- STI ;ALLOW OTHER INTERRUPTS
- PUSH AX ;MUST SAVE PROCESSOR STATE
- IN AL,60H ;GET THE SCAN CODE
- CMP AL,HOTKEY ;IS IT THE HOT KEY?
- JE TRIGGER ;IF YES, CHECK THE MASK
- INT09_EXIT: POP AX ;RESTORE THE PROCESSOR STATE
- JMP OLDINT09 ;CONTINUE WITH ROM ROUTINE
-
- TRIGGER: MOV AH,2 ;GET KEYBOARD STATUS
- INT 16H ;BIOS KEYBOARD SERVICE
-
- AND AL,0FH ;Take lower four bits
- CMP AL,SHIFT_MASK ;IS CTL KEY DOWN?
- JNZ INT09_EXIT ;IF NOT, IGNORE IT
- TEST BUSY_FLAGS,00000100B ;IS SNIPPER ALREADY ACTIVE?
- JNZ INT09_EXIT ;IF ACTIVE, THEN EXIT
- OR BUSY_FLAGS,00000100B ;ITS ACTIVE NOW
- PUSHF
- CALL OLDINT09 ;LET ROM PROCESS THE KEY
- PUSH BX ;MUST PRESERVE ALL REGISTERS
- PUSH CX
- PUSH DX
- PUSH BP
- PUSH SI
- PUSH DI
- PUSH DS
- PUSH ES
- PUSH CS
- POP DS ;SET DS TO CSEG
- MOV AX,BIOS_SEG ;ES POINTS TO BIOS DATA AREA
- MOV ES,AX
- ASSUME DS:CSEG, ES:BIOS_SEG
- CALL GET_CURS_ADDR ;CURSOR ADDRESS FOR THIS PAGE
- PUSH ES:[BX] ;SAVE THE CURSOR LOCATION
- CALL SNIPPER ;DO THE WINDOW
- CALL GET_CURS_ADDR ;CURS0R ADDRESS FOR THIS PAGE
- POP ES:[BX] ;GET BACK CURSOR POSITION
- AND BUSY_FLAGS,11111011B ;SNIPPER IS NOT ACTIVE
- POP ES ;RESTORE ALL REGISTERS
- POP DS
- POP DI
- POP SI
- POP BP
- POP DX
- POP CX
- POP BX
- POP AX
- IRET ;NOW WERE ALL DONE
- NEWINT09 ENDP
- ;---------------------------------------------------------------------;
- ; INTERRUPT 13 ROUTINE. SET BIOS BUST BIT ;
- ;---------------------------------------------------------------------;
- NEWINT13 PROC FAR
- ASSUME DS:NOTHING, ES:NOTHING
- OR BUSY_FLAGS,00000010B ;SET BIOS BUSY BIT
- PUSHF
- CALL OLDINT13 ;DO THE BIOS FUNCTION
- PUSHF ;SAVE RESULT FLAGS
- AND BUSY_FLAGS,11111101B ;CLEAR BIOS BUSY BIT
- POPF ;GET BACK RESULT FLAGS
- STI ;MUST RETURN WITH INTERUPTS ON
- RET 2 ;RETURN BIOS RESULT FLAGS
- NEWINT13 ENDP
- ;---------------------------------------------------------------------;
- ; INTERRUPT 16 ROUTINE. INSERT KEYSTROKES FROM BUFFER ;
- ;---------------------------------------------------------------------;
- NEWINT16 PROC FAR
- ASSUME DS:NOTHING, ES:NOTHING
- PUSH BX
- CMP SEND_KEYS,1 ;SENDING KEYS FROM BUFFER?
- JE INSERT_KEY ;IF YES, THEN GET NEXT ONE
- CMP FILE_SEND_KEYS,1 ;SENDING KEYS FROM BUFFER?
- JE FILE_INSERT_KEY ;IF YES, THEN GET NEXT ONE
- CMP WRIT_FILE,1 ;ANYTHING TO WRITE TO DISK?
- JE CHECK_DOS_STAT ;IF YES, THIS IS THE TIME
- BIOS_KB:
- POP BX
- JMP OLDINT16 ;JUST DO NORMAL KB ROUTINE
- CHECK_DOS_STAT:
- CMP DOS_STAT,0AH ;DOING READ STRING?
- JE BEGIN_NOW ;IF YES, ITS SAFE TO BEGIN
- CMP DOS_STAT,8 ;DOING KEYBOARD INPUT?
- JNE BIOS_KB ;IF YES, ITS SAFE TO BEGIN
- BEGIN_NOW:
- STI ;GET INTERRUPTS BACK ON
- CALL WRITE_TO_FILE ;EMPTY THE BUFFER
- JMP BIOS_KB ;CONTINUE WITH BIOS ROUTINE
- INSERT_KEY:
- STI ;INTERRUPTS BACK ON
- MOV BX,BUFF_NEXT ;GET ADDRESS OF NEXT BYTE
- CMP BX,BUFF_LAST ;AT END OF BUFFER YET?
- JL GET_A_KEY ;IF NOT, GET THE NEXT ONE
- MOV SEND_KEYS,0 ;WHEN DONE, TURN OFF SEND SWITCH
- GET_A_KEY:
- MOV AL,CS:[BX] ;GET THE NEXT KEY CODE
- CMP AL,10 ;IS IT A LINE FEED?
- JNE NOT_LF ;DONT RETURN THE LINE FEEDS
- INC BUFF_NEXT ;SKIP TO NEXT KEY
- JMP INSERT_KEY
- NOT_LF:
- CMP AH,1 ;REQUEST FOR STATUS ONLY?
- JE RETURN_STATUS ;IF YES, RETURN STATUS ONLY
- CMP AH,0 ;REQUEST TO GET THE NEXT KEY
- JNE BIOS_KB ;IF NOT, IGNORE THIS FUNCTION
- INC BX ;REMOVE THIS KEY FROM OUR BUFFER
- MOV BUFF_NEXT,BX ;SAVE THE POINTER TO NEXT KEY
- RETURN_STATUS:
- OR BL,1 ;CLEAR ZERO FLAG TO INDICATE A
- POP BX ;KEY IS AVAILIABLE
- RET 2 ;RETURN WITH THESE FLAGS
- FILE_INSERT_KEY:
- STI ;INTERRUPTS BACK ON
- MOV BX,FILE_BUFF_NEXT ;GET ADDRESS OF NEXT BYTE
- CMP BX,FILE_BUFF_LAST ;AT END OF BUFFER YET?
- JL FILE_GET_A_KEY ;IF NOT, GET THE NEXT ONE
- MOV FILE_SEND_KEYS,0 ;WHEN DONE, TURN OFF SEND SWITCH
- FILE_GET_A_KEY:
- MOV AL,CS:[BX] ;GET THE NEXT KEY CODE
- CMP AL,10 ;IS IT A LINE FEED?
- JNE FILE_NOT_LF ;DONT RETURN THE LINE FEEDS
- INC FILE_BUFF_NEXT ;SKIP TO NEXT KEY
- JMP FILE_INSERT_KEY
- FILE_NOT_LF:
- CMP AH,1 ;REQUEST FOR STATUS ONLY?
- JE FILE_RETURN_STATUS ;IF YES, RETURN STATUS ONLY
- CMP AH,0 ;REQUEST TO GET THE NEXT KEY
- JNE BIOS_KB ;IF NOT, IGNORE THIS FUNCTION
- INC BX ;REMOVE THIS KEY FROM OUR BUFFER
- MOV FILE_BUFF_NEXT,BX ;SAVE THE POINTER TO NEXT KEY
- FILE_RETURN_STATUS:
- OR BL,1 ;CLEAR ZERO FLAG TO INDICATE A
- POP BX ;KEY IS AVAILIABLE
- RET 2 ;RETURN WITH THESE FLAGS
- NEWINT16 ENDP
- ;---------------------------------------------------------------------;
- ; INTERRUPT 21 ROUTINE. THIS ROUTINE IS USED TO MONITOR DOS FUNCTION ;
- ; CALLS. IF THE BUFFER NEEDS TO BE FLUSHED, IT WIL BE DONE HERE. ;
- ;---------------------------------------------------------------------;
- NEWINT21 PROC FAR
- ASSUME DS:NOTHING, ES:NOTHING
- STI
- OR AH,AH ;DOING FUNCTION ZERO?
- JNE NOT_ZERO
- MOV AH,4CH ;IF YES, CHANGE IT TO A 4CH
- NOT_ZERO:
- OR BUSY_FLAGS,00000001B ;SET DOS BUSY BIT
- MOV DOS_STAT,AH
- PUSHF ;SIMULATE AN INTERRUPT
- CALL OLDINT21 ;DO THE DOS FUNCTION
- PUSHF ;SAVE THE RESULT FLAGS
- AND BUSY_FLAGS,11111110B ;CLEAR DOS BUSY BIT
- CMP WRIT_FILE,1 ;ANYTHING TO WRITE TO DISK?
- JNE NO_WRITE ;IF NOT JUST RETURN
- CALL WRITE_TO_FILE ;SAFE TO ACCESS DISK NOW
- NO_WRITE:
- POPF ;RECOVER DOS RESULT FLAGS
- RET 2 ;RETURN WITH DOS RESULT FLAGS
- NEWINT21 ENDP
- ;---------------------------------------------------------------------;
- ; NEW INTERRUPT 24H (CRITICAL DOS ERROR). THIS INTERRUPT IS ONLY IN ;
- ; EFFECT ONLY DURING A WRITE SCREEN. IT IS REQUIRED TO SUPPRESS THE ;
- ; 'ABORT, RETRY, IGNORE' MESSAGE. ALL FATAL DISK ERRORS ARE IGNORED. ;
- ;---------------------------------------------------------------------;
- NEWINT24 PROC FAR
- ASSUME CS:CSEG, DS:NOTHING, ES:NOTHING
- STI ;TURN INTERRUPTS BACK ON
- INC ERR_STAT ;SET THE ERROR FLAG
- XOR AL,AL ;TELLS DOS TO IGNORE THE ERROR
- IRET ;THATS ALL WE DO HERE
- NEWINT24 ENDP
-
- ;--------------------------------------------------------------------;
- ; HERE IS THE CODE USED TO INITIALIZE SNIPPER. ;
- ;--------------------------------------------------------------------;
- ASSUME CS:CSEG, DS:CSEG, ES:CSEG
- INITIALIZE:
- LEA DX,COPYRIGHT
- MOV AH,9 ;DOS DISPLAY STRING SERVICE
- INT 21H ;DISPLAY TITLE MESSAGE
- ; SEARCH FOR AN PREVIOUSLY INSTALLED COPY OF SNIPPER
- NOT BYTE PTR START ;MODIFY TO AVOID FASLE MATCH
- XOR BX,BX ;START SEARCH AT SEGMENT ZERO
- MOV AX,CS ;COMPARE TO THIS CODE SEGMENT
- NEXT_SEGMENT:
- INC BX ;LOOK AT NEXT SEGMENT
- CMP AX,BX ;UNTIL REACHING THIS CODE SEG
- MOV ES,BX
- JE NOT_INSTALLED
- LEA SI,START ;SETUP TO COMPARE STRINGS
- MOV DI,SI
- MOV CX,16 ;16 BYTES MUST MATCH
- REP CMPSB ;COMPARE DS:SI TO ES:DI
- OR CX,CX ;DID THE STRINGS MATCH?
- JNE NEXT_SEGMENT ;IF NO MATCH, TRY NEXT SEGMENT
- LEA DX,INSTALLED_MSG
- JMP SHORT ERR_EXIT
- NOT_INSTALLED:
- MOV AH,30H
- INT 21H ;GET DOS VERSION NUMBER
- CMP AL,2 ;IS IT HIGHER THAN 2.0?
- JNB VER_OK ;IF YES, PROCEED
- LEA DX,BAD_DOS_MSG
- ERR_EXIT:
- MOV AH,9 ;DOS DISPLAY STRING SERVICE
- INT 21H ;DISPLAY ERRER MESSAGE
- RET ;RETURN TO DOS
- EXIT_NON_TSR:
- MOV AH,4CH
- INT 21H
- VER_OK:
- INC SI ;POINT TO FIRST PARAMETER
- MOV SI,81H ;POINT TO PARAMETER AREA
- CALL GET_PARAM ;GET FIRST PARAMETER (ROWS)
- PUSH AX ;SAVE THE ROW COUNT
- CALL GET_PARAM ;GET SECOND PARAMETER (COLUMNS)
- ADD AX,2 ;ADD SPACE FOR CR AND LF
- POP BX ;GET BACK FIRST PARAMETER
- MUL BX ;PRODUCT OF ROWS AND COLUMNS
- OR AX,AX ;WAS ANYTHING ENTERED?
- JE NO_PARAMS ;IF NOT, USE DEFAULT VALUE
- CMP AX,10000 ;MAXIMUM BUFFER IS 10000 BYTES
- JLE SIZE_IS_OK
- MOV AX,10000
- SIZE_IS_OK:
- ADD AX,BUFF_START
- MOV BUFF_END,AX ;SET THE NEW BUFFER SIZE
- NO_PARAMS:
- MOV AX,BIOS_SEG ;LOOK AT BIOS DATA AREA
- MOV ES,AX
- ASSUME ES:BIOS_SEG
- CMP ROWS,0 ;IS NUMBER OF ROWS ENTERED HERE
- JNE MUST_BE_EGA ;IF YES, AN EGA MAY BE PRESENT
- MOV ROWS,24 ;IF NOT EGA, MUST BE 24 ROWS
- MUST_BE_EGA:
- ASSUME ES:NOTHING
- MOV AX,3509H ;GET KEYBOARD BREAK VECTOR
- INT 21H
- MOV WORD PTR [OLDINT09], BX ;SAVE SEGMENT
- MOV WORD PTR [OLDINT09+2],ES ;SAVE OFFSET
- MOV DX, OFFSET NEWINT09
- MOV AX, 2509H
- INT 21H ;DOS FUNCTION TO CHANGE VECTOR
- MOV AX,3513H ;GET BIOS DISK INTERRUPT VECTOR
- INT 21H
- MOV WORD PTR [OLDINT13], BX ;SAVE SEGMENT
- MOV WORD PTR [OLDINT13+2],ES ;SAVE OFFSET
- MOV DX, OFFSET NEWINT13
- MOV AX, 2513H
- INT 21H ;DOS FUNCTION TO CHANGE VECTOR
- MOV AX,3516H ;GET KEYBOARD INPUT VECTOR
- INT 21H
- MOV WORD PTR [OLDINT16], BX ;SAVE SEGMENT
- MOV WORD PTR [OLDINT16+2],ES ;SAVE OFFSET
- MOV DX, OFFSET NEWINT16
- MOV AX, 2516H
- INT 21H ;DOS FUNCTION TO CHANGE VECTOR
- MOV AX,3521H ;GET DOS FUNCTION VECTOR
- INT 21H
- MOV WORD PTR [OLDINT21], BX
- MOV WORD PTR [OLDINT21+2],ES
- MOV DX, OFFSET NEWINT21
- MOV AX, 2521H
- INT 21H ;DOS FUNCTION TO CHANGE VECTOR
- CALL GET_PARAM
- ;--------------------------------------------------------------------;
- ; DEALLOCATE OUR COPY OF THE ENVIORNMENT. ;
- ; EXIT USING INT 27H. LEAVE CODE AND SPACE FOR BUFFER RESIDENT. ;
- ;--------------------------------------------------------------------;
- MOV AX,DS:[002CH] ;GET SEGMENT OF ENVIORNMENT
- MOV ES,AX ;PUT IT INTO ES
- MOV AH,49H ;RELEASE ALLOCATED MEMORY
- INT 21H
- MOV DX,FILE_BUFF_END;LEAVE THIS MUCH RESIDENT
- INT 27H ;TEMINATE AND STAY RESIDENT
- ;---------------------------------------------------------;
- ; GET_PARAM RETRIEVES AN INTEGER FROM THE COMMAND LINE. ;
- ;---------------------------------------------------------;
- GET_PARAM:
- XOR AX,AX ;CLEAR AX FOR TOTAL
- GET_DIGIT:
- MOV BL,[SI] ;GET CHARACTER INTO BL
- CMP BL,0DH ;IS IT THE LAST ONE?
- JE DONE
- INC SI ;POINT TO NEXT CHARACTER
- CMP BL,"," ;IS IT THE DELIMITER?
- JE DONE
- CMP BL,"/" ;IS IT THE DELIMITER?
- JE GET_THE_PATH
- SUB BL,30H ;CONVERT ASCII TO INTEGER
- JB GET_DIGIT ;IS IT A VALID DIGIT
- CMP BL,9
- JA GET_DIGIT ;IF NOT VALID, JUST SKIP IT
- MOV BH,10 ;TIMES 10 FOR NEXT DIGIT
- MUL BH ;MULTIPLY SUM AND ADD THIS DIGIT
- ADD AL,BL ;ADD DIGIT TO SUM
- JMP GET_DIGIT ;READ ALL CHARACTERS ON LINE
- GET_THE_PATH:
- MOV BL,[SI]
- CMP BL,50H
- JE PATH_FLAG_OK
- CMP BL,70H
- JNE DONE
- PATH_FLAG_OK:
- INC SI
- MOV BL,[SI]
- CMP BL,3DH
- JNE DONE
- INC SI
- LEA DI,FILE_PATH
- GET_THE_PATH_LOOP:
- MOV BL,[SI]
- CMP BL,0DH
- JE PATH_DONE
- MOV [DI],BL
- INC SI
- INC DI
- JMP GET_THE_PATH_LOOP
- PATH_DONE:
- MOV BYTE PTR[DI],5CH
- DONE:
- RET
- CSEG ENDS
- END START
-